﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Interpreter;

namespace LogoScriptIDE
{
    /// <summary>
    /// Interaction logic for StackWindow.xaml
    /// 堆栈窗口
    /// </summary>
    public partial class StackWindow : UserControl
    {
        private static readonly int DefaultStringBuilderLength = 256;

        /// <summary>
        /// 堆栈信息
        /// </summary>
        public class Stack
        {
            /// <summary>
            /// 堆栈深度
            /// </summary>
            public int Depth { get; set; }

            /// <summary>
            /// 函数调用所在行数
            /// </summary>
            public int Line { get; set; }

            /// <summary>
            /// 函数名
            /// </summary>
            public string Function { get; set; }
        }

        /// <summary>
        /// 更新堆栈窗口
        /// </summary>
        /// <param name="m">虚拟机</param>
        public void Update(Machine m)
        {
            // 如果虚拟机处于暂停状态，并且代码已经完成编译
            // 那么从虚拟机获取堆栈信息并显示
            // 否则不显示
            if (m != null &&
                (m.Status == MachineStatus.MACHINE_STATUS_PAUSED ||
                m.Status == MachineStatus.MACHINE_STATUS_DEAD) &&
                m.CompileComplete)
            {
                ui_grid.ItemsSource = GetStackSource(m);
            }
            else
            {
                ui_grid.ItemsSource = null;
            }
        }

        /// <summary>
        /// 从虚拟机获取堆栈信息
        /// </summary>
        /// <param name="m">虚拟机</param>
        private List<Stack> GetStackSource(Machine m)
        {
            List<StackInfo> L = m.GetCallStack();
            List<Stack> m_stack = new List<Stack>();
            int depth = L.Count;
            foreach (StackInfo s in L)
            {
                // 获取函数名
                StringBuilder sb = new StringBuilder(DefaultStringBuilderLength);
                sb.Append(s.funcName);
                sb.Append('(');

                // 获取函数调用参数
                if (s.parmList.Count > 0 && s.parmList != null)
                {
                    for (int i = 0; i < s.parmList.Count; i++)
                    {
                        if (i > 0) sb.Append(", ");
                        sb.Append(s.parmList[i].ToString(m));
                    }
                }
                
                sb.Append(')');

                // 新建堆栈信息，并放入堆栈信息列表中
                Stack stack = new Stack();
                stack.Function = sb.ToString();
                stack.Line = s.line;
                stack.Depth = depth;
                --depth;
                m_stack.Add(stack);
            }
            return m_stack;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public StackWindow()
        {
            InitializeComponent();
            Clear();
        }

        /// <summary>
        /// 清空堆栈信息
        /// </summary>
        private void Clear()
        {
            ui_grid.ItemsSource = null;
        }

        /// <summary>
        /// 鼠标双击回调函数
        /// </summary>
        private void ui_grid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            Stack currentItem = ui_grid.SelectedItem as Stack;
            if (currentItem != null)
            {
                doubleClickLine = currentItem.Line;
                MouseDoubleClickFlag = true;
            }
        }

        /// <summary>
        /// 保存是否被鼠标双击
        /// </summary>
        public bool MouseDoubleClickFlag = false;

        /// <summary>
        /// 保存被鼠标双击的行号
        /// </summary>
        public int doubleClickLine { get; set; }
    }
}
